#!/bin/bash
# *************************************
# 功能: k8s管理过程中涉及到的其他软件
# 作者: 王树森
# 联系: wangshusen@sswang.com
# 微信群: 自学自讲—软件工程
# 抖音号: sswang_yys 
# 版本: v0.1
# 日期: 2024-09-07
# *************************************

# 定制Centos的nginx软件源
create_centos_nginx_repo(){
  # 基本变量
  local nginx_base_dir="/tmp/nginx"
  local centos_nginx_dir="${nginx_base_dir}/centos"
  local nginx_repo_path="${centos_nginx_dir}/nginx.repo"
  # 创建基础目录
  # create_not_exist_dir_logic "${centos_nginx_dir}"
  file_oper_logic "local" "create" "dir" "${centos_nginx_dir}"

  # 创建软件源文件
  cat > "${nginx_repo_path}"<<-eof
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=0
enabled=1
eof
}

# 定制Ubuntu的nginx软件源
create_ubuntu_nginx_repo(){
  # 基本变量
  local nginx_base_dir="/tmp/nginx"
  local ubuntu_nginx_dir="${nginx_base_dir}/ubuntu"

  # 创建基础目录
  #  create_not_exist_dir_logic "${ubuntu_nginx_dir}"
  file_oper_logic "local" "create" "dir" "${ubuntu_nginx_dir}"

  # 获取key
  local nginx_key_url="https://nginx.org/keys/nginx_signing.key"
  wget --quiet "${nginx_key_url}" -P "${ubuntu_nginx_dir}"
  
  # 创建repo
  local key_path="/usr/share/keyrings/nginx-archive-keyring.gpg"
  local repo_url="http://nginx.org/packages/ubuntu"
  local repo_path="${ubuntu_nginx_dir}/nginx.list"
  > "${repo_path}"
  for i in focal jammy;do
    echo "deb [signed-by=${key_path}] ${repo_url} $i nginx" >> "${repo_path}"
  done
}

# 定制k8s节点的nginx软件源
create_host_nginx_repo(){
  # 创建文件
  create_centos_nginx_repo
  create_ubuntu_nginx_repo
}

# ubuntu主机创建key文件功能函数
create_ubuntu_nginx_key_func(){
  # 接收参数
  local host_addr="$1"
  local source_key="$2"
  local key_path="/usr/share/keyrings/nginx-archive-keyring.gpg"

  # 生成专属的key文件
  create_cmd="cat ${source_key} | gpg --dearmor | sudo tee ${key_path} >/dev/null"
  ssh "${login_user}@${host_addr}" "${create_cmd}"
}


# 在线方式准备nginx软件源文件
nginx_repo_scp_remote(){
  # 接收参数
  local host_addr="$1"
  local ubuntu_nginx_dir="/tmp/nginx/ubuntu"
  # 创建软件源文件
  create_host_nginx_repo

  # 转移repo文件
  local os_type=$(get_remote_os_type "remote" "${host_addr}")
  if [ "${os_type}" == "Ubuntu" ]; then
    local s_repo_file="${nginx_ls_dir}/ubuntu/nginx.list"
    local d_repo_dir="/etc/apt/sources.list.d"
    scp_file_base_func "${host_addr}" "${s_repo_file}" "${d_repo_dir}"
    local s_key_file="${ubuntu_nginx_dir}/nginx_signing.key"
    local d_key_dir="/tmp"
    scp_file_base_func "${host_addr}" "${s_key_file}" "${d_key_dir}"
    # ubuntu主机生成key文件
    create_ubuntu_nginx_key_func "${host_addr}" "${d_key_dir}/nginx_signing.key"
  elif [ "${os_type}" == "CentOS" ];then
    local s_repo_file="${nginx_ls_dir}/centos/nginx.repo"
    local d_repo_dir="/etc/apt/sources.list.d"
    scp_file_base_func "${host_addr}" "${s_repo_file}" "${d_repo_dir}"
  fi
}

# 获取nginx软件名称后缀
get_nginx_softs_tail(){
  # 接收参数
  local host_addr="$1"
  local get_cmd="apt-cache madison nginx"

  # 获取远程主机系统版本
  local lsb_msg=$(ssh "${login_user}@${host_addr}" "lsb_release -sc")

  # 获取远程主机后缀
  local nginx_tail=$(ssh "${login_user}@${host_addr}" "${get_cmd}" \
                                   | grep "${nginx_ver}" \
                                   | awk "/${lsb_msg}/{print \$3}")
  echo "${nginx_tail}"
}

# 在线方式部署nginx完善配置功能函数
nignx_deploy_online_edit_conf(){
  # 接收参数
  local host_addr="$1"
  local nginx_conf="${nginx_base_path}/nginx.conf"

  # 增加属性信息
  local key_word="keepalive_timeout"
  local value="client_max_body_size 50m;"
  ssh "${login_user}@${host_addr}" "sed -i \"/${key_word}/a\    ${value}\" ${nginx_conf}"
}

# 在线方式部署nginx环境功能函数
nginx_deploy_online(){
  # 接收参数
  local host_addr="$1"
  local softs_name="nginx"

  # 判断远程主机的系统类型
  local os_type=$(get_remote_os_type "remote" "${host_addr}")
  if [ "${os_type}" == "Ubuntu" ]; then
    local repo_update_cmd="update"
    local nginx_tail=$(get_nginx_softs_tail "${host_addr}")
    local nginx_name="${softs_name}=${nginx_tail}"
  elif [ "${os_type}" == "CentOS" ]; then
    local repo_update_cmd="makecache fast"
    local nginx_name="${softs_name}-${nginx_ver}"
  fi

  # 调试：为了保证nginx部署不受离线部署异常
  file_oper_logic "${host_addr}" "create" "dir" "${nginx_base_path}"
  # 远程主机安装软件
  local cmd_type=$(get_remote_cmd_type "remote" "${host_addr}")
  ssh "${login_user}@${host_addr}" "${cmd_type} ${repo_update_cmd}; \
                                    ${cmd_type} install -y ${nginx_name}"
  # 修改配置
  nignx_deploy_online_edit_conf "${host_addr}"
}


# 离线部署nginx的基础软件库环境部署功能函数
nginx_softs_depend_libs_install(){
  # # 接收参数
  local host_addr="$1"

  # 判断远程主机的系统类型
  local os_type=$(get_remote_os_type "remote" "${host_addr}")
  if [ "${os_type}" == "Ubuntu" ]; then
    local lib_list="gcc libpcre3 libpcre3-dev libpcre3-dev zlib1g-dev libssl-dev make"
  elif [ "${os_type}" == "CentOS" ]; then
    local lib_list="gcc gcc-c++ autoconf pcre pcre-devel make automake zlib zlib-devel"
  fi

  # 远程主机安装软件
  local cmd_type=$(get_remote_cmd_type "remote" "${host_addr}")
  ssh "${login_user}@${host_addr}" "${cmd_type} install -y ${lib_list}"
}

# 转移nginx文件到远程主机
nginx_scp_softs_remote(){
  # 接收参数
  local host_addr="$1"
  local s_nginx_file="${nginx_dir}/${nginx_tar}"
  local d_nginx_dir="/tmp"

  # 传输文件
  scp_file_base_func "${host_addr}" "${s_nginx_file}" "${d_nginx_dir}"
  
  # 解压文件
  ssh "${login_user}@${host_addr}" "tar xf ${d_nginx_dir}/${nginx_tar} -C ${d_nginx_dir}"
}

# 定制nginx root配置文件功能函数
nginx_root_conf_create_func(){
  # 接收参数
  local nginx_ls_dir="$1"
  local nginx_conf="${nginx_ls_dir}/nginx.conf"

  # 创建配置
  cat > "${nginx_conf}"<<-eof
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                      '\$status \$body_bytes_sent "\$http_referer" '
                      '"\$http_user_agent" "\$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    client_max_body_size 50m;
    include /etc/nginx/conf.d/*.conf;
}
eof
}

# 转移nginx.conf模版文件到远程主机功能函数
nginx_scp_base_conf_remote(){
  # 接收参数
  local host_addr="$1"
  local s_nginx_file="$2"
  local d_nginx_dir="$3"

  # 传输文件
  scp_file_base_func "${host_addr}" "${s_nginx_file}" "${d_nginx_dir}"
}

# nginx编译配置文件
nginx_remote_configure_func(){
  # 接收参数
  local host_addr="$1"
  local config_dir="$2"
  local name="nginx"
  local prefix_path="/etc/${name}"
  local log_path="/var/log/${name}"
  local pid_path="/var/run/${name}.pid"
  local sbin_path="/usr/sbin/${name}"
  local conf_path="${prefix_path}/${name}.conf"

  # 环境变量
  local configure_cmd="cd ${config_dir}; ./configure --prefix=${prefix_path} --error-log-path=${log_path}/error.log --http-log-path=${log_path}/access.log --pid-path=${pid_path} --sbin-path=${sbin_path} --conf-path=${conf_path} --user=${name} --group=${name} --with-http_ssl_module "

  ssh "${login_user}@${host_addr}" "${configure_cmd}"
}

# nginx编译环境部署功能函数
nginx_remote_make_func(){
  # 接收参数
  local host_addr="$1"
  local config_dir="$2"
  
  # 编译部署
  local make_cmd="cd ${config_dir}; make && make install"
  ssh "${login_user}@${host_addr}" "${make_cmd}"
}

# 定制nginx的基础server配置功能函数 
nginx_html_conf_create_func(){
  # 接收参数
  local nginx_conf="$1"

  # 创建配置
  cat > "${nginx_conf}"<<-eof
server {
        listen       81;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}
eof
}

# 定制nginx的默认server配置文件功能函数
nginx_scp_default_server_remote(){
  # 接收参数
  local host_addr="$1"
  local s_nginx_file="$2"
  local d_nginx_dir="$3"

  # 创建文件
  nginx_html_conf_create_func "${s_nginx_file}"

  # 创建远程目录
  # remote_create_not_exist_dir_logic "${host_addr}" "${d_nginx_dir}"
  file_oper_logic "${host_addr}" "create" "dir" "${d_nginx_dir}"

  # 传输文件
  scp_file_base_func "${host_addr}" "${s_nginx_file}" "${d_nginx_dir}"
}

# 定制nginx服务配置文件功能函数
nginx_service_create_func(){
  # 接收参数
  local service_path="$1"

  # 创建配置
  cat > "${service_path}"<<-eof
[Unit]
Description=nginx - high performance web server
Documentation=https://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP \$(/bin/cat /var/run/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM \$(/bin/cat /var/run/nginx.pid)"

[Install]
WantedBy=multi-user.target
eof
}

# 转移nginx服务文件到远程主机功能函数
nginx_scp_service_remote(){
  # 接收参数
  local host_addr="$1"
  local s_nginx_file="$2"
  local d_nginx_dir="$3"

  # 创建文件
  nginx_service_create_func "${s_nginx_file}"

  # 传输文件
  scp_file_base_func "${host_addr}" "${s_nginx_file}" "${d_nginx_dir}"
}

# 离线方式部署nginx环境功能函数
nginx_deploy_offline(){
  # 接收参数
  local host_addr="$1"

  # 创建基础目录
  local nginx_ls_dir="/tmp/nginx"
  # create_not_exist_dir_logic "${nginx_ls_dir}"
  file_oper_logic "local" "create" "dir" "${nginx_ls_dir}"

  # 创建基础配置文件
  nginx_root_conf_create_func "${nginx_ls_dir}" 
  nginx_html_conf_create_func "${nginx_ls_dir}"

  # 远程主机部署nginx基础软件库环境
  nginx_softs_depend_libs_install "${host_addr}"

  # 转移nginx软件文件到远程主机
  nginx_scp_softs_remote "${host_addr}"

  # 转移nginx配置模版文件到远程主机
  local base_conf="${nginx_ls_dir}/nginx.conf"
  local untar_dir="${nginx_ls_dir}-${nginx_ver}"
  local conf_dir="${untar_dir}/conf"
  nginx_scp_base_conf_remote "${host_addr}" "${base_conf}" "${conf_dir}"

  # nginx编译配置文件
  nginx_remote_configure_func "${host_addr}" "${untar_dir}"

  # nginx安装部署
  nginx_remote_make_func "${host_addr}" "${untar_dir}"

  # nginx服务配置
  local default_conf="${nginx_ls_dir}/default.conf"
  local remote_conf="/etc/nginx/conf.d"
  nginx_scp_default_server_remote "${host_addr}" "${default_conf}" "${remote_conf}"

  # nginx服务文件
  local service_name="nginx.service"
  local service_file="${nginx_ls_dir}/${service_name}"
  local service_dir="/etc/systemd/system"
  nginx_scp_service_remote "${host_addr}" "${service_file}" "${service_dir}"

  # nginx服务初始化
  remote_service_init "${host_addr}" "${service_name}"
}

# 部署nginx
nginx_deploy_logic(){
  # 接收参数
  local host_addr="$1"

  # 部署nginx
  if [ "${default_deploy_type}" == "online" ];then
    nginx_deploy_online "${host_addr}"
  else
    nginx_deploy_offline "${host_addr}"
  fi
}

# 定制nginx移除默认配置功能函数
nginx_default_conf_delete_func(){
  # 接收参数
  local host_addr="$1"

  # 删除默认配置
  local default_conf_path="/etc/nginx/conf.d/default.conf"
  local default_conf_del_cmd="rm -rf ${default_conf_path}"
  ssh "${login_user}@${host_addr}" "${default_conf_del_cmd}"
}
